<template>
  <el-dialog
    title="会员排期"
    :visible.sync="visible"
    width="1300px"
    append-to-body  
    :loading="dialogLoading"
  >
    <!-- 时间选择表单 -->
    <el-form :model="schedulesForm" label-width="120px" class="mb8" ref="schedulesFormRef">
      <el-row :gutter="20">
        <!-- 开始时间 -->
        <el-col :span="11">
          <el-form-item label="开始时间" prop="startTime" :rules="[{required:true,message:'请选择开始时间',trigger:'blur'}]" >
            <el-date-picker
              v-model="schedulesForm.startTime"
              type="date"
              value-format="yyyy-MM-dd"
              placeholder="请选择开始时间"
              style="width: 100%"
              clearable
              :disabled="dialogLoading"
            ></el-date-picker>
          </el-form-item>
        </el-col>
        <!-- 间隔时间天数 -->
        <el-col :span="11">
          <el-form-item 
              label="间隔时间天数" 
              prop="intervalDays" 
              :rules="[
                {
                  required: true, 
                  message: '请输入间隔天数', 
                  trigger: 'blur',
                  validator: (rule, value, callback) => {
                    // 处理空值和空格
                    if (!value || value.toString().trim() === '') {
                      callback(new Error('请输入间隔天数'));
                    } else if (Number(value) < 7) {
                      callback(new Error('间隔天数至少为7'));
                    } else {
                      callback();
                    }
                  }
                }
              ]"
            >
              <el-input
                v-model="schedulesForm.intervalDays"
                type="number"
                placeholder="请输入间隔时间天数"
                style="width: 100%"
                clearable
                :disabled="dialogLoading"
                min="7"
              ></el-input>
            </el-form-item>
        </el-col>
      </el-row>
    </el-form>

    <!-- 操作按钮 -->
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          icon="el-icon-edit"
          size="mini"
          @click="handleAutoGenerateSchedules"
          :disabled="dialogLoading || !schedulesForm.startTime || !schedulesForm.intervalDays || Number(schedulesForm.intervalDays) < 7"
        >
          自动生成排期
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          icon="el-icon-delete"
          size="mini"
          @click="handleDeleteSchedules"
          :disabled="dialogLoading || !checkedSchedulesItems.length"
        >
          删除选中排期
        </el-button>
      </el-col>
      <el-col :span="1.5" v-if="schedulesForm.projectSchedulesList.length">
        <el-button
          type="warning"
          icon="el-icon-refresh"
          size="mini"
          @click="handleClearSchedules"
          :disabled="dialogLoading"
        >
          清空所有排期
        </el-button>
      </el-col>
        <el-col :span="1.5">
          <el-button
            type="success"
            icon="el-icon-plus"
            size="mini"
            @click="handleAddOneRow"
            :disabled="dialogLoading"
          >
            添加一行
          </el-button>
        </el-col>
    </el-row>

    <!-- 排期表格（完善回显） -->
    <el-table
      stripe
      :data="schedulesForm.projectSchedulesList"
      :row-class-name="setTableIndex"
      @selection-change="handleSchedulesSelectionChange"
      ref="schedulesTableRef"
      border
      :loading="dialogLoading"
      v-loading="dialogLoading"
    >
      <el-table-column type="selection" width="50" align="center" />
      <el-table-column label="序号" align="center" prop="attr1" width="50" />
      <!-- 项目选择（下拉回显） -->
      <el-table-column label="项目选择" prop="productName" width="280">
        <template slot-scope="scope">
          <el-select
            v-model="scope.row.productIds" 
            placeholder="请选择项目"
            style="width: 100%"
            multiple
            @change="handleProductChange(scope.row)"
            :disabled="dialogLoading"
          >
            <el-option
              v-for="item in productList"
              :key="item.id"  
              :label="item.productName"
              :value="item.id"  
            ></el-option>
          </el-select>
        </template>
      </el-table-column>
      <!-- 排期时间（自动计算回显，不可编辑） -->
      <el-table-column label="排期时间" prop="schedulesTime" width="220">
        <template slot-scope="scope">
          <el-input
            v-model="scope.row.schedulesTime"
            placeholder="排期时间"
            :disabled="dialogLoading"
          ></el-input>
        </template>
      </el-table-column>
      <el-table-column label="会员昵称" prop="customerName" width="220">
        <template slot-scope="scope">
          <el-input
            v-model="scope.row.customerName"
            placeholder="请输入会员昵称"
            :disabled="dialogLoading"
          ></el-input>
        </template>
      </el-table-column>
      <!-- 排期次数（自动生成回显） -->
      <el-table-column label="排期次数" prop="schedulesNum" width="180">
        <template slot-scope="scope">
          <el-input
            v-model="scope.row.schedulesNum"
            placeholder="排期次数"
            :disabled="dialogLoading"
          ></el-input>
        </template>
      </el-table-column>
      <!-- 备注（支持编辑回显） -->
      <el-table-column label="备注" prop="remark" width="250">
        <template slot-scope="scope">
          <el-input
            v-model="scope.row.remark"
            placeholder="请输入备注（如：第X次服务）"
            :disabled="dialogLoading"
          ></el-input>
        </template>
      </el-table-column>
    </el-table>

    <!-- 底部按钮 -->
    <div slot="footer" class="dialog-footer">
      <el-button
        type="primary"
        @click="handleSubmit"
        :disabled="dialogLoading || !schedulesForm.projectSchedulesList.length"
      >
        确 定 保 存
      </el-button>
      <el-button @click="handleCancel" :disabled="dialogLoading">
        取 消
      </el-button>
    </div>
  </el-dialog>
</template>

<script>
import { listSchedules, addAllSchedules } from "@/api/projects/schedules";
import { listSlProduct } from '@/api/projects/SlProduct';
// 引入日期处理工具（若项目有封装，可替换为自己的工具）
import { formatDate, addDays } from '@/utils/dateUtil';

export default {
  name: 'SchedulesSetting', // 组件名与文件名保持一致，避免混淆
  props: {
    // 1. 弹窗显示状态（与父级.sync绑定）
    visible: {
      type: Boolean,
      required: true,
      default: false,
      validator: (val) => typeof val === 'boolean' // 类型校验
    },
    // 2. 当前项目ID（父级传递：currentProjectForSchedules.id）
    projectId: {
      type: [Number, String],
      required: true,
      default: '',
      validator: (val) => val !== '' // 非空校验
    },
    // 3. 排期总次数（父级传递：currentProjectForSchedules.num）
    projectNum: {
      type: [Number, String],
      required: true,
      default: 1,
      validator: (val) => Number(val) >= 1 // 至少1次
    },
    // 5. 会员ID（父级传递：currentProjectForSchedules.customId）
    projectCustomerId: {
      type: [Number, String],
      required: true,
      default: '',
      description: '父级传递的初始会员ID，用于排期回显'
    },
    // 6. 会员名称（父级传递：currentProjectForSchedules.customName）
    projectCustomerName: {
      type: String,
      required: true,
      default: '',
      description: '父级传递的初始会员名称，用于排期回显'
    },
  },
  data() {
    return {
      // 弹窗加载状态
      dialogLoading: false,
      // 排期表单核心数据（替换原冗余的salaryForm）
      schedulesForm: {
        startTime: '', // 排期开始时间（用户选择）
        intervalDays: '7', // 间隔天数（默认7天，可修改）
        projectSchedulesList: [] // 排期列表（表格数据源）
      },
      // 选中的排期项（用于批量删除）
      checkedSchedulesItems: [],
      // 下拉选项：项目列表（加载所有可选项目）
      productList: [],
      // 表单引用（用于校验）
      schedulesFormRef: null,
      // 表格引用（用于清空选择）
      schedulesTableRef: null
    }
  },
  watch: {
    // 监听弹窗显示状态：打开时加载数据，关闭时重置
    visible: {
      immediate: true, // 初始渲染时执行一次
      handler(newVal) {
        if (newVal) {
          // 弹窗打开：加载项目列表 + 回显历史排期
          this.initSchedulesData();
          this.setCurrentStartTime(); // 弹窗打开时设置当前日期
        } else {
          // 弹窗关闭：重置表单 + 清空选择
          this.resetSchedulesData();
        }
      }
    },
  },
  created() {
    // 初始化：提前加载项目下拉列表（避免弹窗打开时等待）
    this.loadProductSelectData();
  },
  methods: {
   
    // 1. 加载项目下拉列表（用于表格项目选择）
    async loadProductSelectData() {
      this.dialogLoading = true;
      try {
        const res = await listSlProduct({ pageSize: 1000, status: 1 }); // 只加载启用的项目
        if (res.code === 200 && res.rows) {
          this.productList = res.rows;
          // 移除所有与projectName和defaultProductId相关的代码
        } else {
          this.$modal.msgError('项目列表加载失败，请重试');
          this.productList = [];
        }
      } catch (err) {
        console.error('项目列表加载异常：', err);
        this.$modal.msgError('系统异常，项目列表加载失败');
        this.productList = [];
      } finally {
        this.dialogLoading = false;
      }
    },

    // 2. 初始化排期数据（弹窗打开时）：加载历史排期 + 回显父级参数
    async initSchedulesData() {
      this.dialogLoading = true;
      try {
            // 关键：确保项目列表（productList）已加载完成（若未加载则等待加载）
          if (this.productList.length === 0) {
            await this.loadProductSelectData(); // 等待项目列表加载
          }
        // 步骤1：加载当前会员卡的历史排期（若有）
        const res = await listSchedules({ cardId: this.projectId,pageSize: 1000 });
       if (res.code === 200 && res.rows) {
          // 历史排期回显：格式化数据结构
          this.schedulesForm.projectSchedulesList = this.formatSchedulesList(res.rows);
        } else {
          // 无历史排期：初始化空列表（等待用户生成）
          this.schedulesForm.projectSchedulesList = [];
        }

        // 步骤2：回显父级传递的基础参数
        this.schedulesForm.startTime = new Date().toISOString().substring(0, 10);
        this.schedulesForm.intervalDays = this.schedulesForm.intervalDays || '7'; // 默认间隔
        this.$modal.msgSuccess('排期数据加载完成');
      } catch (err) {
        console.error('排期数据初始化异常：', err);
        this.$modal.msgError('排期数据加载失败，请重试');
        this.schedulesForm.projectSchedulesList = [];
      } finally {
        this.dialogLoading = false;
      }
    },

    // 3. 格式化排期列表（统一数据结构，确保回显正常）
    formatSchedulesList(list) {
      return list.map((item, index) => {
            let schedulesTimeDate = null;
            if (item.schedulesTime) {
              // 尝试转换：若字符串格式是 "yyyy-MM-dd" 或 "yyyy-MM-dd HH:mm:ss"，均可正常转换
              schedulesTimeDate = new Date(item.schedulesTime);
              // 校验转换结果：若转换失败（如格式错误），重置为null
              if (isNaN(schedulesTimeDate.getTime())) {
                console.warn(`排期时间转换失败，原始值：${item.schedulesTime}`, item);
                schedulesTimeDate = null;
              }
            }
            // 步骤2：核心修复：统一productIds为数字数组
            const productIds = (() => {
              // 情况1：后台返回的是数组（如 [213, 214] 或 ["213", "214"]）
              if (Array.isArray(item.productIds)) {
                return item.productIds.map(id => Number(id)); // 转成数字数组
              }
              // 情况2：后台返回的是字符串（如 "213" 或 "213,214"）
              if (typeof item.productIds === 'string' && item.productIds.trim()) {
                return item.productIds.split(',').map(id => Number(id)); // 分割后转数字数组
              }
              // 情况3：无值，返回空数组
              return [];
            })();
        
       // 步骤3：筛选匹配的项目（此时productIds是数字数组，p.id是数字，类型一致）
         const selectedProducts = this.productList.filter(p => productIds.includes(p.id));
        const productName = selectedProducts.map(p => p.productName).join('、'); // 正确拼接名称

      return {
          id: item.sId || '', 
          productIds: productIds, 
          productName: productName,
          schedulesTime: formatDate(schedulesTimeDate, 'yyyy-MM-dd'),
          customId: item.customId || this.projectCustomerId || '', // 保留ID用于提交
          customerName: item.customerName || '', // 新增：回显后端的会员昵称
          remark: item.remark || `第1次排期`, // 后续改默认1
          schedulesNum: 1, // 新增：默认排期次数1（后续调整）
          attr1: index + 1
  };
      });
    },


    // 在需要设置当前时间的地方调用（如组件初始化、按钮点击等）
    setCurrentStartTime() {
      const now = new Date();
      // 获取年（4位）、月（补0）、日（补0）
      const year = now.getFullYear();
      const month = String(now.getMonth() + 1).padStart(2, '0'); // 月份是0-11，需+1；不足2位补0
      const day = String(now.getDate()).padStart(2, '0'); // 日期不足2位补0
      // 拼接为 yyyy-MM-dd 格式，赋值给表单
      this.schedulesForm.startTime = `${year}-${month}-${day}`;
    },

      // 新增：单独添加一行排期
  handleAddOneRow() {
    const list = this.schedulesForm.projectSchedulesList;
    // 1. 计算新行的序号（当前列表长度 + 1）
    const newIndex = list.length + 1;
    // 2. 生成默认排期数据（与自动生成的格式一致，关键字段赋默认值）
    const newRow = {
      productIds: [], // 项目ID默认空数组（需用户选择）
      productName: '', // 项目名称默认空（选择项目后自动同步）
      // 排期时间默认：若有开始时间，默认取“开始时间 + 间隔天数 * (列表长度)”；若无则取当前日期
      schedulesTime: this.schedulesForm.startTime 
        ? formatDate(
            addDays(
              new Date(this.schedulesForm.startTime),
              Number(this.schedulesForm.intervalDays) * (list.length)
            ),
            'yyyy-MM-dd'
          )
        : new Date().toISOString().substring(0, 10),
      customId: this.projectCustomerId || '', // 会员ID默认用父级传递的值
      customerName: this.projectCustomerName || '', // 会员昵称默认用父级传递的值
      schedulesNum: 1, // 排期次数默认1（符合需求）
      remark: `第1次排期（手动添加）`, // 备注默认值
      attr1: newIndex // 序号
    };
    // 3. 将新行追加到列表末尾
    this.schedulesForm.projectSchedulesList.push(newRow);
    // 4. 提示用户
    this.$modal.msgSuccess('成功添加一行排期');
  },

    // 4. 自动生成排期（核心功能：根据开始时间、间隔、次数生成）
    handleAutoGenerateSchedules() {
      // 基础校验
      const startDate = new Date(this.schedulesForm.startTime);
      const totalNum = Number(this.projectNum);
      const interval = Number(this.schedulesForm.intervalDays);

      if (isNaN(startDate.getTime())) {
        return this.$modal.msgError('请选择有效的开始时间');
      }
      if (totalNum < 1) {
        return this.$modal.msgError('排期总次数至少为1次');
      }
      if (interval < 1) {
        return this.$modal.msgError('间隔天数至少为1天');
      }

      // 生成排期列表
      const newSchedulesList = [];
      for (let i = 0; i < totalNum; i++) {
        // 计算当前排期时间：开始时间 + 间隔天数 * i
        const currentSchedulesTime = addDays(startDate, interval * i);
          newSchedulesList.push({
          productIds: [], 
          productName: '',
          schedulesTime: formatDate(currentSchedulesTime, 'yyyy-MM-dd'),
          customId: this.projectCustomerId || '', // 保留ID用于提交，不显示在表格
          customerName: this.projectCustomerName || '', // 新增：会员昵称初始为空，允许用户输入
          schedulesNum: 1, // 后续会改默认1，先占位
          remark: `第1次排期（自动生成）`, // 后续改默认1
          attr1: i + 1
        });
      }

      // 更新排期列表（覆盖原有数据）
      this.schedulesForm.projectSchedulesList = newSchedulesList;
      this.$modal.msgSuccess(`成功生成${totalNum}条排期`);
      // 清空表格选择
      if (this.schedulesTableRef) {
        this.schedulesTableRef.clearSelection();
      }
    },

    // 5. 项目选择变化：同步项目名称
      handleProductChange(row) {
        // 筛选选中的项目（类型一致，匹配成功）
        const selectedProducts = this.productList.filter(p => 
          row.productIds.includes(p.id) // 数字数组.includes(数字)
        );
        // 同步显示项目名称
        row.productName = selectedProducts.map(p => p.productName).join('、');
      },
    // 7. 表格选中变化：记录选中项
    handleSchedulesSelectionChange(selection) {
      this.checkedSchedulesItems = selection; // 直接保存选中的行数据（便于删除）
    },

    // 8. 删除选中排期
    handleDeleteSchedules() {
      if (this.checkedSchedulesItems.length === 0) {
        return this.$modal.msgWarning('请先选中要删除的排期');
      }

      this.$modal.confirm(
        `确定要删除选中的${this.checkedSchedulesItems.length}条排期吗？删除后不可恢复`,
        '删除确认',
        { type: 'warning' }
      ).then(async () => {
        this.dialogLoading = true;
        try {
          // 过滤掉选中的排期
          const remainingSchedules = this.schedulesForm.projectSchedulesList.filter(
            item => !this.checkedSchedulesItems.some(checked => checked.attr1 === item.attr1)
          );
          // 重新格式化序号和排期次数
           this.schedulesForm.projectSchedulesList = remainingSchedules.map((item, index) => ({
              ...item,
              attr1: index + 1 // 重新赋值序号，确保连续
            }));
          // 清空选中状态
          this.checkedSchedulesItems = [];
          if (this.schedulesTableRef) {
            this.schedulesTableRef.clearSelection();
          }
          this.$modal.msgSuccess('排期删除成功');
        } catch (err) {
          this.$modal.msgError('排期删除失败，请重试');
        } finally {
          this.dialogLoading = false;
        }
      });
    },

    // 9. 清空所有排期
    handleClearSchedules() {
      this.$modal.confirm(
        '确定要清空所有排期吗？清空后需重新生成',
        '清空确认',
        { type: 'warning' }
      ).then(() => {
        this.schedulesForm.projectSchedulesList = [];
        this.checkedSchedulesItems = [];
        if (this.schedulesTableRef) {
          this.schedulesTableRef.clearSelection();
        }
        this.$modal.msgSuccess('所有排期已清空');
      });
    },

    // 10. 提交排期（保存到后端）
    async handleSubmit() {
      // 表单校验
      this.$refs.schedulesFormRef.validate(async (isValid) => {
        if (!isValid) return; // 校验失败

        // 排期列表校验
        const invalidItem = this.schedulesForm.projectSchedulesList.find(
          item => 
            (Array.isArray(item.productIds) && item.productIds.length === 0) || // 多选未选项目
            !item.schedulesTime || // 无排期时间
            !item.customId // 无会员ID（虽不显示，但需用于提交）
        );
        if (invalidItem) {
          return this.$modal.msgError(`第${invalidItem.attr1}条排期缺少必填项（项目/时间/会员ID）`);
        }
        this.dialogLoading = true;
        try {
          // 构造提交参数（与后端接口对齐）
            const submitData = {
              cardId: Number(this.projectId), // 父级传递的会员卡ID
              intervalDays: Number(this.schedulesForm.intervalDays), // 间隔天数
              projectSchedulesList: this.schedulesForm.projectSchedulesList.map(item => ({
                sId: item.id || null, // 注意这里改为sId与后端对应
                cardId: Number(this.projectId), // 会员卡ID
                productIds: item.productIds.join(','), // 转为逗号分隔的字符串
                schedulesTime: item.schedulesTime, // 排期日期
                customId: Number(item.customId), // 用户ID
                pushState: item.pushState || '0', // 推送状态，默认为0未推送
                remark: item.remark // 备注
              }))
            };

          // 调用保存接口（新增/编辑通用）
          const res = await addAllSchedules(submitData);
          if (res.code === 200) {
            this.$modal.msgSuccess('排期保存成功');
            // 通知父级：保存成功，触发父级刷新
            this.$emit('success', submitData);
            // 关闭弹窗
            this.$emit('update:visible', false);
          } else {
            this.$modal.msgError(res.msg || '排期保存失败');
          }
        } catch (err) {
          console.error('排期提交异常：', err);
          this.$modal.msgError('系统异常，排期保存失败');
        } finally {
          this.dialogLoading = false;
        }
      });
    },

    // 11. 取消操作：关闭弹窗
    handleCancel() {
      // 询问是否放弃修改
      if (this.schedulesForm.projectSchedulesList.length > 0) {
        this.$modal.confirm(
          '当前有未保存的排期数据，确定要取消吗？',
          '取消确认',
          { type: 'info' }
        ).then(() => {
          this.$emit('update:visible', false);
        });
      } else {
        this.$emit('update:visible', false);
      }
    },

    // 12. 重置排期数据（弹窗关闭时）
    resetSchedulesData() {
      this.schedulesForm = {
        startTime: '',
        intervalDays: '7',
        projectSchedulesList: []
      };
      this.checkedSchedulesItems = [];
      if (this.schedulesFormRef) {
        this.$refs.schedulesFormRef.resetFields();
      }
      if (this.schedulesTableRef) {
        this.schedulesTableRef.clearSelection();
      }
    },

    // 13. 设置表格序号
    setTableIndex({ row, rowIndex }) {
      row.attr1 = rowIndex + 1;
    }
  }
}
</script>

<style scoped>
/* 可选：优化表格和按钮样式 */
.el-table {
  margin-bottom: 16px;
}
.el-button--mini {
  margin-right: 8px;
}
.dialog-footer {
  text-align: right;
}
</style>